09. 循环语句-股价涨跌幅提醒

循环:批量金融数据处理的核心工具

金融市场产生海量时间序列数据——股价、成交量、收益率等。

  • 循环结构使我们能够高效处理重复性数据
  • 自动执行批量任务,是金融分析系统的核心工具
  • 本章重点:for循环、while循环与循环控制语句

迭代 vs 递归:两种重复执行模式

模式 含义 金融场景适用性
迭代 重复执行相同操作 ✅ 时间序列天然顺序性
递归 函数调用自身 ❌ 内存消耗大
  • 金融数据处理中,迭代(循环)更为常见
  • 内存消耗可控,更容易理解和调试

For循环:遍历序列的基本语法

for循环用于遍历列表、元组、字符串等可迭代对象。

语法结构:

for item in iterable:
    # 对每个元素执行操作
  • item:每次迭代取出的当前元素
  • iterable:被遍历的序列对象

For循环:四种基本遍历方式

Listing 1
# ==================== 示例1:遍历列表 ====================
stocks = ['中信证券', '国泰君安', '海通证券']
for stock in stocks:
    print(f'分析股票: {stock}')

# ==================== 示例2:遍历字符串 ====================
code = '600519.SH'
for char in code:
    print(char, end=' ')
print()

# ==================== 示例3:遍历范围 ====================
for i in range(5):
    print(f'第{i+1}次迭代')

# ==================== 示例4:遍历字典 ====================
stock_info = {'name': '中信证券', 'code': '600030.SH', 'price': 24.78}
for key in stock_info:
    print(f'{key}: {stock_info[key]}')
分析股票: 中信证券
分析股票: 国泰君安
分析股票: 海通证券
6 0 0 5 1 9 . S H 
第1次迭代
第2次迭代
第3次迭代
第4次迭代
第5次迭代
name: 中信证券
code: 600030.SH
price: 24.78

range()函数:生成整数序列

range()是循环中最常用的工具,用于生成整数序列。

三种调用方式:

语法 说明 示例
range(stop) 从0到stop-1 range(5) → 0,1,2,3,4
range(start, stop) 从start到stop-1 range(2020, 2025)
range(start, stop, step) 指定步长 range(0, 10, 2)

range()函数:实例演示

Listing 2
# 用法1:指定结束值
for i in range(5):
    print(f'i = {i}', end='  ')
print()

# 用法2:指定起始和结束值(遍历年份)
for year in range(2020, 2025):
    print(f'年份: {year}')

# 用法3:指定步长(偶数序列)
for i in range(0, 10, 2):
    print(f'偶数: {i}', end='  ')
print()

# 用法4:负步长(倒序)
for i in range(10, 0, -1):
    print(f'倒计时: {i}', end=' ')
print()
i = 0  i = 1  i = 2  i = 3  i = 4  
年份: 2020
年份: 2021
年份: 2022
年份: 2023
年份: 2024
偶数: 0  偶数: 2  偶数: 4  偶数: 6  偶数: 8  
倒计时: 10 倒计时: 9 倒计时: 8 倒计时: 7 倒计时: 6 倒计时: 5 倒计时: 4 倒计时: 3 倒计时: 2 倒计时: 1 

range()金融应用:生成日期序列

Listing 3
import numpy as np
dates = np.arange('2024-01-01', '2024-01-06', dtype='datetime64[D]')
print('2024年1月前5个工作日:')
for date in dates:
    print(f'  {date}')
2024年1月前5个工作日:
  2024-01-01
  2024-01-02
  2024-01-03
  2024-01-04
  2024-01-05
  • np.arange可生成日期范围,常用于时间序列分析
  • 配合for循环可逐日处理金融数据

While循环:条件驱动的重复执行

while循环在条件为True时重复执行,适用于不确定迭代次数的情况。

语法结构:

while condition:
    # 执行操作
    # 更新条件(重要!)
  • 循环条件最终必须变为False
  • 循环体内必须有更新条件的语句

While循环:简单计数示例

Listing 4
count = 0
while count < 5:
    print(f'计数: {count}')
    count += 1  # 重要:更新循环变量,避免无限循环
# 循环执行5次后,count变为5,条件不再满足
计数: 0
计数: 1
计数: 2
计数: 3
计数: 4

While循环:模拟价格监控

Listing 5
print('价格监控模拟:')
price = 18.00   # 初始价格
target = 20.00  # 目标价格
days = 0        # 天数计数器

while price < target:
    price += 0.50  # 每天价格上涨0.50元
    days += 1
    print(f'第{days}天, 价格: {price:.2f}元')

    if days > 100:  # 安全措施:避免无限循环
        print('达到最大监控天数')
        break

print(f'\n达到目标价20元, 耗时{days}天')
价格监控模拟:
第1天, 价格: 18.50元
第2天, 价格: 19.00元
第3天, 价格: 19.50元
第4天, 价格: 20.00元

达到目标价20元, 耗时4天

While循环:三条安全法则

使用while循环时,必须确保

  1. 循环条件最终会变为False
    • 否则将陷入无限循环
  2. 循环体内有更新条件的语句
    • count += 1price += 0.5
  3. 添加安全措施
    • 设置最大迭代次数:if days > 100: break

循环控制语句:break跳出循环

break语句立即跳出最内层循环,不执行循环体剩余代码。

执行逻辑:

  • 遇到break时,立即退出循环
  • 循环后续代码不再执行
  • 继续执行循环之后的语句

⭐ 平台任务:股价跌幅预警(break)

Listing 6
# ⚠️ 平台原始代码 - 请原样输入至教学平台(注释除外),平台才会判定答案正确
r_list=[0.0192,-0.0001,0.006,0.0074,-0.0127,-0.0067,0.0095,-0.0095]  # 定义每日涨跌幅列表
for i in r_list:  # 逐日遍历涨跌幅数据
    if i<-0.01:  # 判断当日跌幅是否超过1%
        break  # 发现跌幅超限,立即跳出循环
print('涨跌幅数据',i)  # 输出触发跌幅预警时的涨跌幅值
涨跌幅数据 -0.0127

平台任务代码深度解析

执行过程追踪:

  • 遍历 0.0192 → 不满足 < -0.01,继续
  • 遍历 -0.0001 → 不满足,继续
  • 遍历 0.006 → 不满足,继续
  • 遍历 0.0074 → 不满足,继续
  • 遍历 -0.0127满足! 执行break跳出

关键知识点: 循环变量i在循环外仍可访问,保持最后一次赋值

break的金融应用场景

场景 说明
止损触发 价格触及止损位立即平仓
异常检测 发现异常数据停止处理
目标达成 达到盈利目标退出监控
  • break立即跳出最内层循环
  • 循环后的代码照常执行

循环控制语句:continue跳过当前迭代

continue语句跳过当前迭代的剩余代码,直接进入下一次迭代。

Listing 7
returns = [0.0192, -0.0001, 0.006, 0.0074, -0.0127, 0.0095]

print('正收益交易日:')
count = 0
for r in returns:
    if r < 0:       # 如果收益率为负
        continue    # 跳过本次迭代,直接进入下一次
    count += 1
    print(f'  第{count}个正收益日: {r:.2%}')

print(f'\n总计正收益日: {count}天')
正收益交易日:
  第1个正收益日: 1.92%
  第2个正收益日: 0.60%
  第3个正收益日: 0.74%
  第4个正收益日: 0.95%

总计正收益日: 4天

break vs continue 对比

关键字 作用 后续代码 循环是否继续
break 跳出整个循环 不执行 ❌ 否
continue 跳过本次迭代 不执行 ✅ 是
  • break:发现目标或异常,停止循环
  • continue:过滤数据,跳过不需要处理的部分

循环中的else子句

Python循环可以带else子句:循环正常结束时执行,被break中断时不执行

Listing 8
# 场景1:循环正常结束 → 执行else
prices = [10, 11, 12, 13, 14]
for price in prices:
    if price > 20:
        print('发现高价股票')
        break
else:
    print('所有股票价格都在合理范围')

print('=' * 50)

# 场景2:循环被break中断 → 不执行else
prices2 = [10, 11, 25, 13, 14]
for price in prices2:
    if price > 20:
        print('发现高价股票')
        break
else:
    print('所有股票价格都在合理范围')
所有股票价格都在合理范围
==================================================
发现高价股票

循环else金融应用:数据验证

Listing 9
prices = [24.78, 20.15, 14.03, 22.41, 16.17]

for price in prices:
    if price <= 0:
        print(f'发现异常价格: {price}')
        break
else:
    print('✓ 所有价格数据有效')
# 这种 for-else 模式在金融数据清洗中非常常用
✓ 所有价格数据有效
  • 循环正常结束(未发现异常)→ 执行else
  • 循环被break中断(发现异常)→ 跳过else

实战案例:股价涨跌幅监控系统

综合运用for循环、if条件判断、break语句:

  • 模拟一周股价数据
  • 逐日计算涨跌幅并判断市场状态
  • 触发预警时自动停止监控

股价监控系统:完整实现

Listing 10
import numpy as np

# 模拟一周股价数据
np.random.seed(42)
base_price = 20.0
price_changes = np.random.randn(5) * 0.5
prices = base_price + np.cumsum(price_changes)

print('=' * 60)
print('股价涨跌幅监控系统')
print('=' * 60)

alert_threshold = -0.01  # 跌幅超过-1%触发警报

for i, price in enumerate(prices, 1):
    if i == 1:
        daily_return = 0
    else:
        daily_return = (price - prices[i-2]) / prices[i-2]

    return_pct = daily_return * 100

    if daily_return < alert_threshold:
        status = '⚠️ 警告'; action = '考虑减仓'
    elif daily_return > 0.01:
        status = '✓ 上涨'; action = '继续持有'
    else:
        status = '正常'; action = '观望'

    print(f'\n{i}天:')
    print(f'  收盘价: {price:.2f}元')
    print(f'  涨跌幅: {return_pct:+.2f}%')
    print(f'  状态: {status}  建议: {action}')

    if daily_return < alert_threshold:
        print('\n' + '=' * 60)
        print('触发风险预警,系统暂停监控')
        print('=' * 60)
        break
else:
    print('\n' + '=' * 60)
    print('一周监控结束,市场表现平稳')
    print('=' * 60)
============================================================
股价涨跌幅监控系统
============================================================

第1天:
  收盘价: 20.25元
  涨跌幅: +0.00%
  状态: 正常  建议: 观望

第2天:
  收盘价: 20.18元
  涨跌幅: -0.34%
  状态: 正常  建议: 观望

第3天:
  收盘价: 20.50元
  涨跌幅: +1.60%
  状态: ✓ 上涨  建议: 继续持有

第4天:
  收盘价: 21.26元
  涨跌幅: +3.71%
  状态: ✓ 上涨  建议: 继续持有

第5天:
  收盘价: 21.15元
  涨跌幅: -0.55%
  状态: 正常  建议: 观望

============================================================
一周监控结束,市场表现平稳
============================================================

嵌套循环:处理二维数据

处理多只股票 × 多个交易日的数据时,需要使用嵌套循环。

执行逻辑:

  • 外层循环遍历交易日
  • 内层循环遍历每只股票
  • 时间复杂度为 \(O(n \times m)\)

嵌套循环:多股票收益统计

Listing 11
returns = [
    [0.01, 0.02, -0.01, 0.03, 0.02],   # 股票A
    [0.02, -0.01, 0.03, 0.01, -0.02],   # 股票B
    [-0.01, 0.03, 0.02, -0.02, 0.01]    # 股票C
]
stock_names = ['股票A', '股票B', '股票C']

print('每日正收益股票统计:\n')
for day in range(5):
    positive_count = 0
    positive_stocks = []
    for stock_idx in range(3):
        if returns[stock_idx][day] > 0:
            positive_count += 1
            positive_stocks.append(stock_names[stock_idx])
    print(f'第{day+1}天: {positive_count}只上涨 → {", ".join(positive_stocks)}')
每日正收益股票统计:

第1天: 2只上涨 → 股票A, 股票B
第2天: 2只上涨 → 股票A, 股票C
第3天: 2只上涨 → 股票B, 股票C
第4天: 2只上涨 → 股票A, 股票B
第5天: 2只上涨 → 股票A, 股票C

循环性能优化:四种方法对比

Listing 12
import time
import numpy as np

n = 100000
list1 = list(range(n))
list2 = list(range(n))

# 方法1:Python for循环
start = time.time()
result_loop = []
for i in range(n):
    result_loop.append(list1[i] + list2[i])
loop_time = time.time() - start

# 方法2:列表推导
start = time.time()
result_listcomp = [list1[i] + list2[i] for i in range(n)]
listcomp_time = time.time() - start

# 方法3:zip+列表推导
start = time.time()
result_zip = [a + b for a, b in zip(list1, list2)]
zip_time = time.time() - start

# 方法4:NumPy向量化
arr1 = np.array(list1)
arr2 = np.array(list2)
start = time.time()
result_numpy = arr1 + arr2
numpy_time = time.time() - start

print(f'Python循环:  {loop_time:.4f}秒')
print(f'列表推导:    {listcomp_time:.4f}秒')
print(f'zip方法:     {zip_time:.4f}秒')
print(f'NumPy向量化: {numpy_time:.4f}秒')
safe_numpy_time = numpy_time if numpy_time > 0 else 1e-12
print(f'\n最快方法比最慢快 {loop_time/safe_numpy_time:.1f}倍')
#print(f'\n最快方法比最慢快 {loop_time/numpy_time:.1f}倍')
Python循环:  0.0133秒
列表推导:    0.0104秒
zip方法:     0.0040秒
NumPy向量化: 0.0000秒

最快方法比最慢快 13308763504.0倍

性能优化总结

方法 速度 适用场景
for循环 最慢 简单逻辑、学习阶段
列表推导 较快 中等规模数据
zip+推导 较快 多列表并行操作
NumPy向量化 最快 大规模金融数据(推荐)
  • NumPy使用C语言实现,通常比纯Python循环快100-1000倍
  • 量化交易中必须使用NumPy/Pandas处理大数据

本章核心知识回顾

知识点 关键语法 金融场景
for循环 for x in seq: 遍历股票列表
while循环 while cond: 价格监控
break 跳出循环 止损触发
continue 跳过当前迭代 过滤异常数据
for-else 正常结束执行else 数据完整性验证
嵌套循环 双层for 多股票多日分析